"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具删除目录及其内容
Create At   : 2023/4/14
Owner       : opentestcase019
Description :
    1.删除空目录，指定-p path参数为正常值，指定/不指定-r参数
    2.删除目录及其内容，指定-r参数
    3.删除目录及其内容，不指定-r参数
    4.删除目录及其内容，指定-p path参数为异常值
    5.删除目录及其内容，指定-U UDS:socket_domain参数为正常值
    6.删除目录及其内容，指定错误的-U UDS:socket_domain参数
    7.删除目录及其内容，指定权限不足的socket_domain
    8.在备机执行删除目录及其内容
    9.在集群停止的情况下执行
    10.在dss关闭的情况下执行
Expect      :
    1.删除成功
    2.删除成功
    3.合理报错
    4.合理报错
    5.删除成功
    6.合理报错Failed to get uds connection.
    7.合理报错Failed to get uds connection.
    8.删除成功
    9.合理报错
    10.合理报错
History     :
"""
import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.dir_name = "dir_dsscmd_0024"
        self.file_name = "file_dsscmd_0024"
        self.dir_name_not_exists = "dir_dsscmd_0024_not_exists"
        self.dir_name_64chars = \
            "dir_dsscmd_0024_dir_dsscmd_0024_dir_dsscmd_0024_dir_0024_64chars"
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vgname = execute_msg.splitlines()[1].split()[0].strip()
        self.logger.info(self.vgname)
        self.dir_path = os.path.join(self.vgname, self.dir_name)
        self.dir_path_64chars = os.path.join(self.vgname, self.dir_name_64chars)
        self.dir_path_not_exists = os.path.join(self.vgname,
                                                self.dir_name_not_exists)
        self.file_path = os.path.join(self.vgname, self.dir_name,
                                      self.file_name)

    def test_sharestorage_tool(self):
        step1 = "-----step1:删除空目录，指定-p path参数为正常值，" \
                "指定/不指定-r参数;expect:删除成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd rmdir -p +{self.dir_path};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd rmdir -p +{self.dir_path} -r"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            f"Succeed to make dir, path is +{self.vgname}, "
            f"dir name is {self.dir_name}."), "执行失败" + step1)
        self.assertEquals(2, execute_msg.count(
            f"Succeed to rm dir, path is +{self.dir_path}"), "执行失败" + step1)

        step2 = "-----step2:删除目录及其内容，指定-r参数;expect:删除成功-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rmdir -p +{self.dir_path} -r"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to make dir, path is +{self.vgname}, "
                      f"dir name is {self.dir_name}.",
                      execute_msg, "执行失败" + step2)
        self.assertIn(f"Succeed to create file, name is +{self.file_path}.",
                      execute_msg, "执行失败" + step2)
        self.assertIn(f"Succeed to rm dir, path is +{self.dir_path}",
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:删除目录及其内容，不指定-r参数;expect:合理报错-----"
        self.logger.info(step3)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rmdir -p +{self.dir_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Failed to rm dir +{self.dir_path}, which has sub node",
                      execute_msg, "执行失败" + step3)

        step4 = "-----step4:删除目录及其内容，指定-p path参数为异常值;expect:合理报错-----"
        self.logger.info(step4)
        cmd_list = [f'+{self.dir_path_not_exists}', f'+{self.dir_name_64chars}',
                    f'+{self.dir_path}目录', f'{self.dir_path}%@',
                    f'{self.dir_path}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd rmdir -p {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd == cmd_list[0]:
                self.assertIn(f"Failed to rm dir, path is "
                              f"+{self.dir_path_not_exists}.",
                              execute_msg, "执行失败" + step4)
            elif cmd == cmd_list[1]:
                self.assertIn("Path  decode error name length should less "
                              "than 64", execute_msg, "执行失败" + step4)
            elif cmd == cmd_list[2]:
                self.assertIn(f"decode error , path should be "
                              f"[0~9,a~z,A~Z,-,_,/,.]",
                              execute_msg, "执行失败" + step4)
            else:
                self.assertIn(f"decode error , path should start with +.",
                              execute_msg, "执行失败" + step4)

        step5 = "-----step5:删除目录及其内容，指定-U UDS:socket_domain参数" \
                "为正常值;expect:删除成功-----"
        self.logger.info(step5)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rmdir -p +{self.dir_path} -r -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to rm dir, path is +{self.dir_path}",
                      execute_msg, "执行失败" + step5)

        step6 = "-----step6:删除目录及其内容，指定错误的-U UDS:socket_domain参数;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rmdir -p +{self.dir_path} -r -U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step6)

        step7 = "-----step7:删除目录及其内容，指定权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"chmod 000 {macro.UDS_PATH[4::]};" \
            f"dsscmd rmdir -p +{self.dir_path} -r -U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step7)

        step8 = "-----step8:在备机执行删除目录及其内容;expect:删除成功-----"
        self.logger.info(step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rmdir -p +{self.dir_path} -r -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(f"Succeed to rm dir, path is +{self.dir_path}",
                      execute_msg, "执行失败" + step8)

        step9 = "-----step9:在集群停止的情况下执行;expect:合理报错-----"
        self.logger.info(step9)
        stop_msg = Primary_SH.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step9)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rmdir -p +{self.dir_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step9)
        start_msg = Primary_SH.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, "执行失败" + step9)

        step10 = "-----step10:在dss关闭的情况下执行;expect:合理报错-----"
        self.logger.info(step10)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd stopdss;" \
            f"sleep 2;" \
            f"dsscmd rmdir -p +{self.dir_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step10)

    def tearDown(self):
        self.logger.info("-----恢复环境-----")
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        if "cluster_state   : Normal" not in status:
            start_msg = Primary_SH.exec_cm_ctl(mode='start')
            self.logger.info(start_msg)
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '恢复环境失败')
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
